package com.ruoyi.common.core.web.component;

import com.ruoyi.common.core.constant.CommonException;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.BaseException;
import com.ruoyi.common.core.exception.domain.ExceptionMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.ExecutorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException;

import javax.servlet.http.HttpServletResponse;
import java.sql.SQLSyntaxErrorException;
import java.util.Objects;

@RestControllerAdvice
@Order(998)
@Slf4j
public class BaseExceptionHandler {

    @Autowired
    private LocaleMessageSourceHandler messageSourceHandler;

    @ExceptionHandler(BaseException.class)
    public R handler(BaseException ex, HttpServletResponse response) {
        if (ex.getLevelEnum().getLevel() == ExceptionMessage.LevelEnum.INFO.getLevel()) {
            log.info(ex.toString());
        } else if (ex.getLevelEnum().getLevel() == ExceptionMessage.LevelEnum.WARN.getLevel()) {
            log.warn(ex.toString());
        } else {
            log.error(ex.getMessage(), ex);
        }
        response.setStatus(ex.getStatus());
        return R.error(ex);
    }

    @ExceptionHandler(SQLSyntaxErrorException.class)
    public R handler(SQLSyntaxErrorException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        return handler(new CommonException(CommonException.DATABASE_EXCEPTION).setBusinessMessage(messageSourceHandler.getMessage("DATABASE_EXCEPTION",null,"数据库异常")), response);
    }

    @ExceptionHandler(ExecutorException.class)
    public R handler(ExecutorException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        return handler(new CommonException(CommonException.DATABASE_EXCEPTION).setBusinessMessage(messageSourceHandler.getMessage("DATABASE_EXCEPTION",null,"数据库异常")), response);
    }

    @ExceptionHandler(HttpClientErrorException.class)
    public R<Object> handler(HttpClientErrorException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        org.springframework.http.HttpStatus httpStatus = ex.getStatusCode();
        response.setStatus(httpStatus.value());
        return R.restResult(null, httpStatus.name(), httpStatus.getReasonPhrase());
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public R<Object> handler(MissingServletRequestParameterException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        BaseException commonException = new CommonException(CommonException.BAD_REQUEST).setBusinessMessage(ex.getMessage());
        return handler(commonException, response);
    }


    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<Object> handler(MethodArgumentNotValidException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        BaseException commonException = new CommonException(CommonException.BAD_REQUEST).setBusinessMessage(Objects.requireNonNull(ex.getBindingResult().getFieldError()).getDefaultMessage());
        return handler(commonException, response);
    }

    @ExceptionHandler(BindException.class)
    public R<Object> handler(BindException ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        BaseException commonException = new CommonException(CommonException.BAD_REQUEST).setBusinessMessage(Objects.requireNonNull(ex.getBindingResult().getFieldError()).getDefaultMessage());
        return handler(commonException, response);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public R<Object> handler(IllegalArgumentException ex,HttpServletResponse response){
        log.error(ex.getMessage(), ex);
        BaseException commonException = new CommonException(CommonException.BAD_REQUEST).setBusinessMessage(ex.getMessage());
        return handler(commonException, response);
    }

/*    @ExceptionHandler(Exception.class)
    public R handler(Exception ex, HttpServletResponse response) {
        log.error(ex.getMessage(), ex);
        BaseException e = new BaseException(ex.getMessage());
        response.setStatus(e.getStatus());
        return R.error(e);
    }*/
}
